summaryrefslogtreecommitdiffstats
path: root/src/android/app/src/main/java/org/yuzu/yuzu_emu/utils/DocumentsTree.kt
diff options
context:
space:
mode:
Diffstat (limited to 'src/android/app/src/main/java/org/yuzu/yuzu_emu/utils/DocumentsTree.kt')
-rw-r--r--src/android/app/src/main/java/org/yuzu/yuzu_emu/utils/DocumentsTree.kt110
1 files changed, 110 insertions, 0 deletions
diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/utils/DocumentsTree.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/utils/DocumentsTree.kt
new file mode 100644
index 000000000..a4795ca22
--- /dev/null
+++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/utils/DocumentsTree.kt
@@ -0,0 +1,110 @@
+package org.yuzu.yuzu_emu.utils
+
+import android.net.Uri
+import androidx.documentfile.provider.DocumentFile
+import org.yuzu.yuzu_emu.YuzuApplication
+import org.yuzu.yuzu_emu.model.MinimalDocumentFile
+import java.io.File
+import java.util.*
+
+class DocumentsTree {
+ private var root: DocumentsNode? = null
+
+ fun setRoot(rootUri: Uri?) {
+ root = null
+ root = DocumentsNode()
+ root!!.uri = rootUri
+ root!!.isDirectory = true
+ }
+
+ fun openContentUri(filepath: String, openMode: String?): Int {
+ val node = resolvePath(filepath) ?: return -1
+ return FileUtil.openContentUri(YuzuApplication.appContext, node.uri.toString(), openMode)
+ }
+
+ fun getFileSize(filepath: String): Long {
+ val node = resolvePath(filepath)
+ return if (node == null || node.isDirectory) {
+ 0
+ } else FileUtil.getFileSize(YuzuApplication.appContext, node.uri.toString())
+ }
+
+ fun exists(filepath: String): Boolean {
+ return resolvePath(filepath) != null
+ }
+
+ private fun resolvePath(filepath: String): DocumentsNode? {
+ val tokens = StringTokenizer(filepath, File.separator, false)
+ var iterator = root
+ while (tokens.hasMoreTokens()) {
+ val token = tokens.nextToken()
+ if (token.isEmpty()) continue
+ iterator = find(iterator, token)
+ if (iterator == null) return null
+ }
+ return iterator
+ }
+
+ private fun find(parent: DocumentsNode?, filename: String): DocumentsNode? {
+ if (parent!!.isDirectory && !parent.loaded) {
+ structTree(parent)
+ }
+ return parent.children[filename]
+ }
+
+ /**
+ * Construct current level directory tree
+ * @param parent parent node of this level
+ */
+ private fun structTree(parent: DocumentsNode) {
+ val documents = FileUtil.listFiles(YuzuApplication.appContext, parent.uri!!)
+ for (document in documents) {
+ val node = DocumentsNode(document)
+ node.parent = parent
+ parent.children[node.name] = node
+ }
+ parent.loaded = true
+ }
+
+ private class DocumentsNode {
+ var parent: DocumentsNode? = null
+ val children: MutableMap<String?, DocumentsNode> = HashMap()
+ var name: String? = null
+ var uri: Uri? = null
+ var loaded = false
+ var isDirectory = false
+
+ constructor()
+ constructor(document: MinimalDocumentFile) {
+ name = document.filename
+ uri = document.uri
+ isDirectory = document.isDirectory
+ loaded = !isDirectory
+ }
+
+ private constructor(document: DocumentFile, isCreateDir: Boolean) {
+ name = document.name
+ uri = document.uri
+ isDirectory = isCreateDir
+ loaded = true
+ }
+
+ private fun rename(name: String) {
+ if (parent == null) {
+ return
+ }
+ parent!!.children.remove(this.name)
+ this.name = name
+ parent!!.children[name] = this
+ }
+ }
+
+ companion object {
+ @JvmStatic
+ fun isNativePath(path: String): Boolean {
+ return if (path.isNotEmpty()) {
+ path[0] == '/'
+ } else false
+ }
+ }
+}